package com.itlv.recursion.business.service.impl;

import com.itlv.recursion.business.mapper.MenuMapper;
import com.itlv.recursion.common.result.Result;
import com.itlv.recursion.common.result.ResultEnum;
import com.itlv.recursion.common.util.AssertUtil;
import com.itlv.recursion.common.util.PubUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itlv.recursion.business.domain.Menu;
import com.itlv.recursion.business.service.MenuService;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单 业务逻辑层 具体实现
 *
 * @author Lv
 * @date 2022/10/22
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    /**
     * 加载树状结构菜单列表
     *
     * @return
     */
    @Override
    public Result<List<Menu>> listMenuTree() {
        List<Menu> menuList = this.list();
        // 处理菜单数据为树状结构
        List<Menu> treeDataList = dealTreeData(menuList);
        return Result.success(treeDataList);
    }

    /**
     * 处理菜单数据为树状结构 无限制层级
     *
     * @param menuList 菜单数据集合
     * @return
     */
    private List<Menu> dealTreeData(List<Menu> menuList) {
        // 处理相同父级id的元素到一个list集合中
        Map<Integer, List<Menu>> map = new HashMap<>(16);
        for (Menu menu : menuList) {
            if (!map.containsKey(menu.getParentId())) {
                List<Menu> menus = new LinkedList<>();
                menus.add(menu);
                map.put(menu.getParentId(), menus);
            } else {
                List<Menu> menus = map.get(menu.getParentId());
                menus.add(menu);
            }
        }

        // 获取父级集合
        List<Menu> dataList = map.get(0);
        // 断言非空处理
        AssertUtil.notEmpty(dataList, ResultEnum.DATA_NOT_EXIST);

        // 递归封装处理子集
        recursionTreeChild(map, dataList);

        return dataList;
    }

    /**
     * 递归封装处理子集
     *
     * @param map      所有菜单数据
     * @param dataList 父级集合
     */
    private void recursionTreeChild(Map<Integer, List<Menu>> map, List<Menu> dataList) {
        for (Menu menu : dataList) {
            // 添加子级菜单
            if (map.containsKey(menu.getId())) {
                List<Menu> menuChildList = map.get(menu.getId());
                menu.setChildList(menuChildList);
                // 递归调用
                recursionTreeChild(map, menuChildList);
            }
        }
    }
}
